package com.sugon.controller.module;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.sugon.annotation.AutoLog;
import com.sugon.annotation.DataFilter;
import com.sugon.annotation.LimitSubmit;
import com.sugon.annotation.NonBusinessParamValid;
import com.sugon.consts.MoldReplacePartType;
import com.sugon.dao.ModuleReplacePartDao;
import com.sugon.entity.*;
import com.sugon.modules.base.model.vo.BaseApproveParamVO;
import com.sugon.modules.base.model.vo.ProcessProgressConst;
import com.sugon.modules.mold.consts.MoldReplacePartProgress;
import com.sugon.modules.mold.consts.MoldSpStockState;
import com.sugon.modules.mold.model.vo.ModuleReplacePartParam;
import com.sugon.modules.mold.service.IMoldReplacePartManager;
import com.sugon.service.*;
import com.sugon.utils.ProcessInfoEnum;
import com.sugon.utils.R;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * 模具-备件更换记录Controller
 *
 * @author YuXD
 * @date 2020-11-11 21:10
 */
@Controller
@RequestMapping("modulereplacepart")
public class ModuleReplacePartController {

    @Autowired
    private ModuleReplacePartService moduleReplacePartService;
    @Autowired
    private IMoldReplacePartManager moldReplacePartManager;
    @Autowired
    private ModuleReplacePartDao moduleReplacePartDao;
    @Autowired
    private ModulPositionCorrelationService moldPosCorrelationService;
    @Autowired
    private SysProcessInfoService sysProcessInfoService;
    @Autowired
    private SysMsgService sysMsgService;
    @Autowired
    private ModuleArchivesService moduleArchivesService;
    @Autowired
    private ModuleSpStockService moduleSpStockService;
    @Autowired
    private ModuleSpPurchasingBatchService moduleSpPurchasingBatchService;
    @Autowired
    private ModuleRepairRocordService moduleRepairRocordService;
    @Autowired
    private ModuleMaintainPlanService moduleMaintainPlanService;
    @Resource
    private ModuleSpDeptStockService moldSpDeptStockService;

    /**
     * 查看列表
     */
    @RequestMapping("/list")
//    @RequiresPermissions("modulereplacepart:list")
    @DataFilter(deptAlias = "MRP.DEPT_CODE", userAlias = "MRP.CREATE_USER")
    @ResponseBody
    public R list(@RequestParam Map<String, Object> params) {
        return R.ok().put("page", moldReplacePartManager.queryList(params));
    }

    /**
     * 查看信息
     */
    @RequestMapping("/info/{id}")
//    @RequiresPermissions("modulereplacepart:info")
    @ResponseBody
    public R info(@PathVariable("id") String id) {
        ModuleReplacePartEntity moduleReplacePart = moduleReplacePartService.queryObject(id);

        return R.ok().put("moduleReplacePart", moduleReplacePart);
    }

    @AutoLog("添加模具换件记录")
    @RequestMapping("/save")
    @RequiresPermissions("modulereplacepart:save")
    @ResponseBody
    @NonBusinessParamValid
    public R save(@Validated @RequestBody ModuleReplacePartParam moduleReplacePartParam, BindingResult bindingResult) {
        // 校验本次需要更换的模具位置列表 中是否有上一次未结束的
        List<String> moldPositionList = moduleReplacePartParam.getMoldPositionList();
        for (String moldPositionId : moldPositionList) {
            // 校验位置是否存在
            ModulPositionCorrelationEntity moldPosition = moldPosCorrelationService.queryObject(moldPositionId);
            if (moldPosition == null) {
                return R.error("模具位置[{}]不存在，请确认！", moldPositionId);
            }
            if (moduleReplacePartDao.countUnPassedReplaceRecordNum(moldPositionId) > 0) {
                return R.error("当前模具位置换件流程尚未结束，请耐心等待！");
            }
        }
        // 校验这个工单是否已换件结束  CQA-NE-00046_20220107 维护工单
        // MREP-20210428-0003 维修工单
        Integer typeMethod = moduleReplacePartParam.getTypeMethod();
        if (MoldReplacePartType.REPAIR.getValue().equals(typeMethod)) {
            // 模具维修工单
            ModuleRepairRocordEntity moldRepairRecord = moduleRepairRocordService.queryByCode(moduleReplacePartParam.getReplaceCode());
            Assert.notNull(moldRepairRecord);
            if (StrUtil.isEmpty(moldRepairRecord.getMoldId())) {
                return R.error("请先关联模具后再进行换件操作！");
            }
            if (MoldReplacePartProgress.PASSED.equals(moldRepairRecord.getProgress())) {
                return R.error("已审批通过，不允许继续添加换件记录！");
            }
        } else if (MoldReplacePartType.MAINTENANCE.getValue().equals(typeMethod)) {
            // 模具维护工单
            ModuleMaintainPlanEntity maintainPlanEntity = moduleMaintainPlanService.queryByCode(moduleReplacePartParam.getReplaceCode());
            Assert.notNull(maintainPlanEntity);
            if (MoldReplacePartProgress.PASSED.equals(maintainPlanEntity.getReplacePartProgress())) {
                return R.error("已审批通过，不允许继续添加换件记录！");
            }
        }
        ModuleArchivesEntity moduleArchives = moduleArchivesService.queryObject(moduleReplacePartParam.getMoldId());
        Assert.notNull(moduleArchives, "模具信息不存在，模具编码:{}", moduleReplacePartParam.getMoldId());
        // 设置模具使用次数
        moduleReplacePartParam.setUseTime(moduleArchives.getUseNo());
        moduleReplacePartParam.setDeptCode(moduleArchives.getSubShop());
        return moldReplacePartManager.addMoldReplacePartRecord(moduleReplacePartParam) ? R.ok() : R.error();
    }

    @LimitSubmit(key = "associateMoldSpStock:%s")
    @AutoLog("模具换件记录关联型芯库存")
    @RequestMapping("/associateMoldSpStock")
    @ResponseBody
    public R associateMoldSpStock(@RequestParam("replacePartRecordId") String replacePartRecordId, @RequestParam("stockId") String stockId) {
        // 校验换件记录是否存在
        ModuleReplacePartEntity moduleReplacePart = moduleReplacePartService.queryObject(replacePartRecordId);
        if (moduleReplacePart == null) {
            return R.error("换件记录不存在，请确认！");
        }
        // 校验是否已关联
        if (StrUtil.isNotEmpty(moduleReplacePart.getStockId())) {
            return R.error("换件记录已关联型芯！");
        }
        // 校验型芯备件是否存在
        ModuleSpStockEntity moduleSpStock = moduleSpStockService.queryObject(stockId);
        if (moduleSpStock == null) {
            return R.error("型芯记录不存在，请确认！");
        }
        // 校验是否已使用
        if (MoldSpStockState.USED.equals(moduleSpStock.getState())) {
            return R.error("型芯备件已使用，请更换！");
        }
        // 校验下当前模具型芯是否适用于这个模具位置
        ModulPositionCorrelationEntity moldPosition = moldPosCorrelationService.queryObject(moduleReplacePart.getModulePositionId());
        Assert.notNull(moldPosition, "模具换件位置不存在！");
        String barCodeRange = moldPosition.getBarCodeRange();
        if (StrUtil.isEmpty(barCodeRange)) {
            return R.error("当前模具位置未配置适用型芯规则，暂不支持换件操作！");
        }else{
            List<String> barCodeList = StrUtil.split(barCodeRange,"|");
            if(!barCodeList.contains(moduleSpStock.getUniqueBarCode())){
                return R.error("当前备件不适用于当前模具位置，请确认！");
            }
        }
        moduleReplacePart.setStockId(stockId);
        if (moduleReplacePartService.update(moduleReplacePart) > 0) {
            // 更新库存状态和备件采购批次数
            moduleSpStock.setState(MoldSpStockState.USED);
            moduleSpStock.setStockOutDate(DateUtil.date());
            if (moduleSpStockService.update(moduleSpStock) > 0) {
                // 实时更新采购批次中的出库数
                moldSpDeptStockService.realtimeUpdateDeptStock(moduleSpStock.getWorkshop(), moduleSpStock.getMoldSpId());
                // 实时更新采购批次中的出库数
                moduleSpPurchasingBatchService.realtimePurchasingBacthStockState();
            }
        }
        return R.ok();
    }

    /**
     * 修改
     */
    @AutoLog("镶件、型芯、镶件更换记录修改")
    @RequestMapping("/update")
    @RequiresPermissions("modulereplacepart:update")
    @ResponseBody
    public R update(@RequestBody ModuleReplacePartEntity moduleReplacePart) {
        moduleReplacePartService.update(moduleReplacePart);

        return R.ok();
    }

    /**
     * 删除
     */
    @AutoLog("镶件、型芯、镶件更换记录删除")
    @RequestMapping("/delete")
    @RequiresPermissions("modulereplacepart:delete")
    @ResponseBody
    public R delete(@RequestBody String[] ids) {
        for (String id : ids) {
            ModuleReplacePartEntity moduleReplacePart = moduleReplacePartService.queryObject(id);
            if (moduleReplacePart == null) {
                continue;
            }
            Integer progress = moduleReplacePart.getProgress();
            if (ProcessProgressConst.PASSED.equals(progress)) {
                return R.error("已审核通过的换件记录不允许删除！");
            }
            if (moduleReplacePartService.delete(id) > 0) {
                // 1、恢复模具关联位置模次同步功能
                ModulPositionCorrelationEntity moldPositionCorrelation = new ModulPositionCorrelationEntity();
                moldPositionCorrelation.setId(moduleReplacePart.getModulePositionId());
                moldPositionCorrelation.setIsNewSyn(1);
                moldPosCorrelationService.update(moldPositionCorrelation);
                // 2、删除换件流程记录
                sysProcessInfoService.delete(ProcessInfoEnum.MDE_BJGH, id);
                // 3、删除所有通知消息
                sysMsgService.delSysMsgService(moduleReplacePart.getId(), ProcessInfoEnum.MDE_BJGH.name(), null);
            }
        }
        return R.ok();
    }

    /**
     * 查看所有列表
     */
    @RequestMapping("/queryAll")
    @ResponseBody
    public R queryAll(@RequestParam Map<String, Object> params) {

        List<ModuleReplacePartEntity> list = moduleReplacePartService.queryList(params);

        return R.ok().put("list", list);
    }

    /**
     * 审核
     */
    @NonBusinessParamValid
    @RequestMapping("/review")
    @RequiresPermissions("modulereplacepart:review")
    @ResponseBody
    public R review(@Validated @RequestBody BaseApproveParamVO approveParam, BindingResult bindingResult) {
        approveParam.setProcessItem(ProcessInfoEnum.MDE_BJGH);
        return moldReplacePartManager.workshopApprove(approveParam) ? R.ok() : R.error();
    }

}
